package com.androidcentralmedias;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;

public class Play extends Activity {
	private UpdateTxt updateTxt = new UpdateTxt();
	public static String canal = new String();
	public static String endereco = new String();
	//Variaveis da seekbar
	public static int delay_inicial = 600;
	public static int delay_pause = 400;
	public static int delay_seek = 1000;
	public int wait_update;
	public Boolean rodando = false;
	public Boolean stop = false;
	public long time = 0;
	long max = -1;
	int lastProgressChange;
	private SeekBar seekBar = null;
	private TextView progressText = null;
	private TextView maxText = null;
	
	//Converte time(ms) para time(hh:mm:ss)
	public String parseTime(long t){
		String h,m,s;
		long hr,mn,sg;
		hr = 0;
		mn = 0;
		sg = 0;
		t = (int)Math.floor(t/1000);
		sg = t % 60;
		if ( t > 59 ) {
			t -= sg;
			t /= 60;
			mn = t % 60;
			if ( t > 59 ) {
				t -= mn;
				t /= 60;
				hr = t % 60;
			}
		}
		//Hora
		h = String.valueOf(hr);
		if ( h.length() == 1 ) h = "0".concat(h);
		h = h.concat(":");
		//Minutos
		m = String.valueOf(mn);
		if ( m.length() == 1 ) m = "0".concat(m);
		m = m.concat(":");
		//Segundos
		s = String.valueOf(sg);
		if ( s.length() == 1 ) s = "0".concat(s);
		if ( hr > 0 )
			return (h.concat(m).concat(s));
		return (m.concat(s));
	}
	
	//Async task que roda no fundo pegando o tempo e atualizando a seekbar/tv
	private class UpdateTxt extends AsyncTask<Void, String, String> {
		
		protected void onPreExecute() {
			stop = false;
			time = 0;
			max = getMax();
			//Erro: timeout do comando getMax
			if (max == -2) {
				seekBar.setVisibility(seekBar.INVISIBLE);
				progressText.setVisibility(progressText.INVISIBLE);
				maxText.setVisibility(maxText.INVISIBLE);
				maxText.setText("");
				progressText.setText("");
				rodando = false;;
			}
			else {
				seekBar.setIndeterminate(false);
				 seekBar.setFocusable(true);
				seekBar.setMax((int)Math.floor(max/1000));
				maxText.setText(parseTime(max));
				seekBar.setMax((int)Math.floor(max/1000));
		        rodando = true;
			}
		}
		
        protected String doInBackground(Void...params) {
        	long delay_threshold = 800;
        	long remoteTime;
        	long dt0, dt;
        	dt0 = 0;
	    	try {
	    		Thread.sleep(delay_inicial);
	    	}
	    	catch (Exception e) {
	    		Log.d("ERR","Cant wait: " + e.getMessage());
			}
			Log.d("WIFI","Max: " + max);
			while ( time < max && !isCancelled() ) {
				if ( rodando ) {
					try {
			    		Thread.sleep(1000);
			    		time += 1000;
			    		//Pedir tempo remoto a cada 3 segs
						if ( (time/1000)%3 == 2 || wait_update > 0 ) {
							if ( wait_update > 0 ) wait_update -= delay_seek;
							Client.enviar("?time:" + canal, MainActivity.type,1);
							remoteTime = -1;
							while(remoteTime == -1) {
								if (MainActivity.parse_msg) {
									if (MainActivity.mensagem.contains("?time:") ) {
										remoteTime = Long.parseLong(MainActivity.mensagem.split(":")[1]);
										Log.d("WIFI","Remote time: " + remoteTime);
									}
									dt = time - remoteTime;
									if ( (dt-dt0) > delay_threshold || (dt-dt0) < -delay_threshold) {
										dt0 = dt;
										time = remoteTime;
									}
									time = remoteTime;
									MainActivity.parse_msg = false;
								}
							}
						}
						publishProgress(Long.toString(time));
			    	}
			    	catch (InterruptedException e) {
						// TODO: handle exception
			    		Log.d("ERR","53: Cant wait: " + e.getMessage());
					}
				}
			}
			return null;
        }
        
        protected void onPostExecute(String result) {
        	if (max == -2) {
				seekBar.setVisibility(seekBar.VISIBLE);
				progressText.setVisibility(progressText.VISIBLE);
				maxText.setVisibility(maxText.VISIBLE);
        		stop = true;
        	}
        	else {
	        	Log.d("ERR","Finished playing. ");
	        	seekBar.setIndeterminate(true);
	            seekBar.setFocusable(false);
	            progressText.setText("--:--");
	        	rodando = false;
	        	stop = true;
        	}
		}
		
        protected void onCancelled() {
			if (max == -2) {
				seekBar.setVisibility(seekBar.VISIBLE);
				progressText.setVisibility(progressText.VISIBLE);
				maxText.setVisibility(maxText.VISIBLE);
				stop = true;
        	}
        	else {
		        // TODO Auto-generated method stub
	        	Log.d("ERR","53: Cancelling... ");
	        	seekBar.setIndeterminate(true);
	            seekBar.setFocusable(false);
	            progressText.setText("--:--");
	        	rodando = false;
	        	stop = true;
        	}
        }

	    protected void onProgressUpdate(String... txt) {
	    	progressText.setText(parseTime(Long.parseLong(txt[0])));
	    	seekBar.setProgress(Integer.parseInt(txt[0])/1000);
	    }
	 }
	
	//Pega a duracao do stream
	public Long getMax () {
		long mx = -1;
		long t0 = System.nanoTime();
		long t;
		Client.enviar("?get_max:" + canal, MainActivity.type,1);
		while(mx == -1) {
			t=System.nanoTime();
			if (MainActivity.parse_msg) {
				if (MainActivity.mensagem.contains("?get_max:") ) {
					mx = Long.parseLong(MainActivity.mensagem.split(":")[1]);
				}
				MainActivity.parse_msg = false;
			}
			if ( t-t0 > 1200000) Client.enviar("?get_max:" + canal, MainActivity.type,1);
		}
		return mx;
	}
	
	public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.play);
        final Button playButton = (Button) findViewById(R.id.play);
        final Button stopButton = (Button) findViewById(R.id.stop);
        final Button proxButton = (Button) findViewById(R.id.proximo);
        final Button anteButton = (Button) findViewById(R.id.anterior);
        final Button fullButton = (Button) findViewById(R.id.fullscreen);
        final Button muteButton = (Button) findViewById(R.id.mute);
        seekBar = (SeekBar) findViewById(R.id.seek);
    	progressText = (TextView) findViewById(R.id.progress);
    	maxText = (TextView) findViewById(R.id.max);
		progressText.setText("--:--");
		maxText.setText("--:--");
        seekBar.setIndeterminate(true);
        seekBar.setFocusable(false);
		playButton.setText("| |");
		
		//Roda update da UI no plano de fundo
		updateTxt.execute();
		
		//Botao Play/Pause
        playButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	Client.enviar("?play:" + canal, MainActivity.type,1);
            	if (playButton.getText() == ">"){
            		playButton.setText("| |");
            		//Rodando pela primeira vez
            		if ( stop ) {
						updateTxt = new UpdateTxt();
            			//Roda o update da seekbar/tv
            			updateTxt.execute();
            		}
            		//Tempo para voltar a rodar
            		else {
            				try {
            					Thread.sleep(delay_pause);
            				} catch ( InterruptedException e) {
            					//Do nothing
            				}
            		}
            		rodando = true;
            	}
            	else {
            		playButton.setText(">");
            		//SeekBar para de ser updated
            		rodando = false;
            	}
    	}});
        muteButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	Client.enviar("?mute", MainActivity.type,2);
            	if (muteButton.getText() == "unmute"){
            		muteButton.setText("mute");
            	}
            	else {
            		muteButton.setText("unmute");
            	}
    	}});
        stopButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	//Resetando a seekbar
            	updateTxt.cancel(true);
            	Client.enviar("?stop:" + canal, MainActivity.type,1);
            	Client.enviar("?stop", MainActivity.type,2);
            	stop = true;
				finish();
    	}});
        proxButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	updateTxt.cancel(true);
            	Client.enviar("?prox:" + canal, MainActivity.type,1);
				//Resetando a seekbar

            	while (!updateTxt.isCancelled()){
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            	}
            	updateTxt = new UpdateTxt();
                updateTxt.execute();
    	}});
        anteButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	updateTxt.cancel(true);
            	Client.enviar("?ante:" + canal, MainActivity.type,1);
				//Resetando a seekbar

                while (!updateTxt.isCancelled()){
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            	}
                updateTxt = new UpdateTxt();
                updateTxt.execute();
    	}});
        fullButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	Client.enviar("?full", MainActivity.type,2);
    	}});
        
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
			
			public void onStopTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				Client.enviar("?seek:" + lastProgressChange + ":"+ canal, MainActivity.type,1);
				rodando = false;
				progressText.setText(parseTime(lastProgressChange));
				seekBar.setProgress(lastProgressChange/1000);
				wait_update = delay_seek;
				time = lastProgressChange;
				if (playButton.getText().equals("| |"))
					rodando = true;	
			}
			
			public void onStartTrackingTouch(SeekBar seekBar) {
				// TODO Auto-generated method stub
				
			}			
			
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
				if ( fromUser ) {
					lastProgressChange = progress*1000;
					//XXX: mandar comando seek (int) atraves do term
					
				}
			}

			
		});
    }
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		updateTxt.cancel(true);
		//Client.enviar("?stop:" + canal, MainActivity.type,1);
	}
}
